//方法1
//service层
//利用自己写的请求进行发送
package com.jzj.jzjctripapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzj.jzjctripapi.config.ConstantConfig;
import com.jzj.jzjctripapi.domain.entity.JzjCompany;
import com.jzj.jzjctripapi.domain.response.AuthenticationInfoListResponse;
import com.jzj.jzjctripapi.domain.request.AuthenticationListRequst;
import com.jzj.jzjctripapi.domain.response.ErrorMessage;
import com.jzj.jzjctripapi.domain.request.AuthenticationInfoList;
import com.jzj.jzjctripapi.config.TicketConfig;
import com.jzj.jzjctripapi.domain.entity.AuthencationEntity;
import com.jzj.jzjctripapi.domain.entity.Personinfo;
import com.jzj.jzjctripapi.domain.entity.UserCardInfoEntity;
import com.jzj.jzjctripapi.mapper.JzjCompanyMapper;
import com.jzj.jzjctripapi.mapper.PersoninfoMapper;
import com.jzj.jzjctripapi.service.PersoninfoService;

import com.jzj.jzjctripapi.utils.HttpUtil;
import com.jzj.jzjctripapi.utils.JsonUtil;
import com.jzj.jzjctripapi.utils.RequestEntityUtil;
import com.sun.org.apache.bcel.internal.generic.NEW;
import corp.openapicalls.contract.ordercontroller.ticket.OrderSearchTicketResponse;
import corp.openapicalls.service.ticket.CorpTicketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author Mazhenming
 * @Description 针对表【personinfo】的数据库操作Service实现
 * @CreateDate 2023-11-06 15:13:47
 */
@Service
@Slf4j
public class PersoninfoServiceImpl extends ServiceImpl<PersoninfoMapper, Personinfo>
        implements PersoninfoService {

    @Autowired
    private PersoninfoMapper personinfoMapper;

    @Autowired
    private JzjCompanyMapper jzjCompanyMapper;


    @Override
    public List<Personinfo> selectAll() {
        return personinfoMapper.selectAll();
    }

    @Override
    public Page<Personinfo> getDataListBySql(Page page) {
        return null;
    }

    /**
     * 定时更新
     * 全员数据
     * 发送每页数据
     */
    public void sendDataToThirdParty() {
        //获取Ticket
        OrderSearchTicketResponse ticketResponse = getEmployeeSyncTicket(TicketConfig.APP_KEY, TicketConfig.APP_SECURITY, "1.0");

        int pageSize = 500;//每页条数
        int currentPage = 1;//当前页
        int cp = 1;
        // 使用MyBatis-Plus进行分页查询
        Page<Personinfo> page1 = Page.of(currentPage, pageSize);
        page1.addOrder(new OrderItem("alias", true));
        Page<Personinfo> dataPage = personinfoMapper.getDataListBySql(page1);
        long pages = dataPage.getPages();

        //当天时间
        LocalDate today = LocalDate.now();

        for (currentPage = 1; currentPage <= pages; currentPage++) {
            log.info("正在发送第"+cp+"分页的值");
            // 使用MyBatis-Plus进行分页查询
            Page<Personinfo> page2 = Page.of(cp, pageSize);
            page2.addOrder(new OrderItem("username",true));
            IPage<Personinfo> dataPage2 = personinfoMapper.getDataListBySql1(page2, String.valueOf(today));
            List<Personinfo> dataList3 = dataPage2.getRecords();//查询的总记录数放入集合
            if (dataList3.isEmpty()) {
                log.info("【查询数据为空，无可发送数据】");
                break; // 没有数据了，结束循环
            }
            //将dataList集合数据进行封装为发送实体
            AuthenticationListRequst authenticationListRequst = buildAuthenticationListRequst(dataList3, ticketResponse.getTicket());
            log.info("【正在发送】第"+cp+"分页的值,"+"发送的实体authenticationListRequst=" + authenticationListRequst);

            //发送的消息，发送dataList到第三方接口
            saveCorpCustInfoList(ticketResponse, authenticationListRequst);
            log.info("发送第"+cp+"分页的值"+"【完成】");

            if (!dataPage.hasNext()) {
                log.info("【数据发送全部完成】，无数据发送");
                break; // 没有下一页数据了，结束循环
            }
            cp++;//页数+1
        }
    }

    /**
     * 传单个人员
     */
    public void sendDataToThirdPartyOnce() {
        String alias="000001";
        //获取Ticket
        OrderSearchTicketResponse ticketResponse = getEmployeeSyncTicket(TicketConfig.APP_KEY, TicketConfig.APP_SECURITY, "1.0");

        int pageSize = 500;//每页条数
        int currentPage = 1;//当前页
        int cp = 1;
        // 使用MyBatis-Plus进行分页查询
        Page<Personinfo> page1 = Page.of(currentPage, pageSize);
        page1.addOrder(new OrderItem("alias", true));
        Page<Personinfo> dataPage = personinfoMapper.getDataListBySql(page1);
        long pages = dataPage.getPages();

        for (currentPage = 1; currentPage <= pages; currentPage++) {
            log.info("正在发送第"+cp+"分页的值");
            // 使用MyBatis-Plus进行分页查询
            Page<Personinfo> page2 = Page.of(cp, pageSize);
            page2.addOrder(new OrderItem("username",true));
            IPage<Personinfo> dataPage2 = personinfoMapper.getDataListBySql2(page2, alias);
            List<Personinfo> dataList3 = dataPage2.getRecords();//查询的总记录数放入集合
            if (dataList3.isEmpty()) {
                log.info("【查询数据为空，无可发送数据】");
                break; // 没有数据了，结束循环
            }
            //将dataList集合数据进行封装为发送实体
            AuthenticationListRequst authenticationListRequst = buildAuthenticationListRequst(dataList3, ticketResponse.getTicket());
            log.info("【正在发送】第"+cp+"分页的值,"+"发送的实体authenticationListRequst=" + authenticationListRequst);

            //发送的消息，发送dataList到第三方接口
            saveCorpCustInfoList(ticketResponse, authenticationListRequst);
            log.info("发送第"+cp+"分页的值"+"【完成】");

            if (!dataPage.hasNext()) {
                log.info("【数据发送全部完成】，无数据发送");
                break; // 没有下一页数据了，结束循环
            }
            cp++;//页数+1
        }
    }

    /**
     * 延时更新
     * 全员数据
     * 每半分钟发送500条数据数据
     */
    public void sendDataToThirdPartyAll() throws InterruptedException {
        //获取Ticket
        OrderSearchTicketResponse ticketResponse = getEmployeeSyncTicket(TicketConfig.APP_KEY, TicketConfig.APP_SECURITY, "1.0");

        int pageSize = 500;//每页条数
        int currentPage = 1;//当前页
        int cp = 1;
        // 使用MyBatis-Plus进行分页查询
        Page<Personinfo> page1 = Page.of(currentPage, pageSize);
        page1.addOrder(new OrderItem("alias", true));
        Page<Personinfo> dataPage = personinfoMapper.getDataListBySql(page1);
        long pages = dataPage.getPages();

        for (currentPage = 1; currentPage <= pages; currentPage++) {
            log.info("正在发送第"+cp+"分页的值");
            // 使用MyBatis-Plus进行分页查询
            Page<Personinfo> page2 = Page.of(cp, pageSize);
            page2.addOrder(new OrderItem("username",true));
            IPage<Personinfo> dataPage2 = personinfoMapper.getDataListBySql(page2);
            List<Personinfo> dataList3 = dataPage2.getRecords();//查询的总记录数放入集合
            if (dataList3.isEmpty()) {
                log.info("【查询数据为空，无可发送数据】");
                break; // 没有数据了，结束循环
            }
            //将dataList集合数据进行封装为发送实体
            AuthenticationListRequst authenticationListRequst = buildAuthenticationListRequst(dataList3, ticketResponse.getTicket());
            log.info("【正在发送】第"+cp+"分页的值,"+"发送的实体authenticationListRequst=" + authenticationListRequst);

            //发送的消息，发送dataList到第三方接口
            saveCorpCustInfoList(ticketResponse, authenticationListRequst);
            log.info("发送第"+cp+"分页的值"+"【完成】");

            if (!dataPage.hasNext()) {
                log.info("【数据发送全部完成】，无数据发送");
                break; // 没有下一页数据了，结束循环
            }
            cp++;//页数+1
            Thread.sleep(30000); // 延时30秒（30000毫秒）
        }
    }


    /**
     * @param @param  ticket
     * @param @return 设定文件
     * @return SaveCorpCustInfoList    返回类型
     * @throws
     * @Title: buildSaveCorpCustInfoList
     * @Description: 构建批量人事更新契约请求
     */
    public AuthenticationListRequst buildAuthenticationListRequst(List<Personinfo> personinfoList, String ticket) {
        //过滤:离职人员，公司空值
       /* List<Personinfo> personinfoList = dataList.stream()
                .filter(data -> data.getZlzrq() == null && data.getKostl() !=null && data.getKostl() !="")
                .collect(Collectors.toList());*/

        List<JzjCompany> jzjCompanyList = jzjCompanyMapper.selectAllCompany();//公司查询集合
        if (Objects.isNull(personinfoList)) {
            return null;
        }

        AuthenticationListRequst authenticationListRequst = new AuthenticationListRequst();//人员信息请求实体
        List<AuthenticationInfoList> authenticationInfoLists = new ArrayList<>();//请求一级实体集合

        personinfoList.stream().forEach(personinfo -> {
            AuthenticationInfoList authenticationInfoList = new AuthenticationInfoList();//发送人员信息实体
            AuthencationEntity authencationEntity = new AuthencationEntity();//人员信息实体
            UserCardInfoEntity userCardInfoEntity = new UserCardInfoEntity();//身份信息
            List<UserCardInfoEntity> userCardInfoEntitys = new ArrayList<>();//身份信息集合

            //人员信息
            authencationEntity.setName(personinfo.getName());//姓名
            authencationEntity.setEmployeeID(personinfo.getAlias());//工号
            authencationEntity.setEmail(personinfo.getEmail());//邮箱
            if (personinfo.getZlzrq() == null) {//字段为空-在职
                authencationEntity.setValid("A");//在职情况（A-在职，I-离职）
            } else {
                authencationEntity.setValid("I");//在职情况（A-在职，I-离职）
            }
            authencationEntity.setDept1(personinfo.getStorename());//部门1

            //公司  截取字段kostl前4位，匹配公司表
            /*if (StringUtils.hasText(personinfo.getKostl())){
                System.out.println("公司id==="+personinfo.getKostl());
            }*/
            String companyId = personinfo.getKostl().substring(0,  Math.min(4, personinfo.getKostl().length()));
            // 公司为空
            int companyIds = Integer.parseInt(companyId);
            for (JzjCompany jzjCompany : jzjCompanyList) {
                if (jzjCompany.getCompanyID() == companyIds) {
                    authencationEntity.setDept2(jzjCompany.getCompanyFullName());//公司全称
                }
            }
            authencationEntity.setSubAccountName(ConstantConfig.SUB_ACCOUNT_NAME);//固定值：JZJ_测试（携程提供）
            authencationEntity.setMobilePhone(personinfo.getMobilephone());//手机号
            authencationEntity.setRankName(personinfo.getJob());//员工差标职级
            //关闭非员工预订权限，默认传值63，代表不允许添加外部人员不传则为允许为外部人员预订
            authencationEntity.setUserTRFlag("63");//固定在： 员工预定权限
            authencationEntity.setCropCardType("B");//固定在：B(代订卡)
            authencationEntity.setResRange("C");//固定在：C(公司)

            //身份信息
            userCardInfoEntity.setCardNo(personinfo.getIdcard());//证件号码
            userCardInfoEntity.setCardType(1);//默认值：（1，身份证）证件类型（不可重复）
            userCardInfoEntity.setIDCardTimelimit("");//证件有效期
            //P：因私     I：因公    D：外交
            userCardInfoEntity.setPassportType("");//证件护照类型(当CardType=2时必填)

            userCardInfoEntitys.add(userCardInfoEntity);//添加身份信息集合
            authencationEntity.setUserCardInfos(userCardInfoEntitys);//人员信息实体添加身份信息实体集合

            authenticationInfoList.setSequence(personinfo.getAlias());//默认值0（建议随即值）(员工工号)
            authenticationInfoList.setAuthentication(authencationEntity);//添加人员信息实体集合

            authenticationInfoLists.add(authenticationInfoList);//添加请求集合
        });
        //请求信息实体
        authenticationListRequst.setLanguage("zh-CN");
        authenticationListRequst.setAppkey(TicketConfig.APP_KEY);
        authenticationListRequst.setTicket(ticket);
        authenticationListRequst.setCorporationID(ConstantConfig.CORP_ID);
        authenticationListRequst.setAuthenticationInfoList(authenticationInfoLists);

        //调用测试环境服务请把注释代码放开
        //authenticationListRequst.setRequestUrlType(corp.openapicalls.common.RequestUrlEnum.FAT);

        return authenticationListRequst;
    }

    /**
     * @param appKey      接入账号
     * @param appSecurity 接入密码
     * @param @return     设定文件
     * @return TicketResponse    返回类型
     * @throws
     * @Title: getEmployeeSyncTicket
     * @Description: 获取人事更新的令牌Ticket
     */
    public OrderSearchTicketResponse getEmployeeSyncTicket(String appKey, String appSecurity, String version) {
        //调用测试环境服务请把注释代码放开
        //CorpTicketService testService=new CorpTicketService(corp.openapicalls.common.RequestUrlEnum.FAT);
        return CorpTicketService.getEmployeeSyncTicket(appKey, appSecurity, version);
    }


    /**
     * @param
     * @return 返回类型
     * @throws
     * @Title: SaveCorpCustInfoList
     * @Description: 验证返回的ticketResponse
     */
    public AuthenticationInfoListResponse saveCorpCustInfoList(OrderSearchTicketResponse ticketResponse, AuthenticationListRequst authenticationListRequst) {
        AuthenticationInfoListResponse authenticationInfoListResponse = new AuthenticationInfoListResponse();
        //获取到的ticket
        if (ticketResponse != null && ticketResponse.getStatus() != null && ticketResponse.getStatus().getSuccess()) {
            //System.out.println("get ticket success! ticket:" + ticketResponse.getTicket());

            // 发送批次数据到第三方接口
            authenticationInfoListResponse = sendData(authenticationListRequst);

            // 处理响应结果
            //返回错误契约信息
            authenticationInfoListResponse = sendListResponse(authenticationInfoListResponse);

        } else {
            //System.out.println("获取ticketResponse错误：" + JSON.toJSONString(ticketResponse));
            log.error("获取ticketResponse错误：" + JSON.toJSONString(ticketResponse));
        }
        return authenticationInfoListResponse;
    }


    /**
     * 发送返回契约消息
     *
     * @param authenticationInfoListResponse
     * @return
     */
    public AuthenticationInfoListResponse sendListResponse(AuthenticationInfoListResponse authenticationInfoListResponse) {
        // 处理响应结果
        //返回错误契约信息
        if (authenticationInfoListResponse != null) {
            String result = authenticationInfoListResponse.getResult();
            // 返回失败
            if ("Failed".equals(result) || "Contains errors".equals(result)) {
                List<ErrorMessage> errorMessages = authenticationInfoListResponse.getErrorMessageList();
                if (errorMessages != null && !errorMessages.isEmpty()) {
                    for (ErrorMessage errorMessage : errorMessages) {
                        //System.out.println(JSONObject.toJSONString(errorMessage));
                        log.error(JSONObject.toJSONString(errorMessage));
                    }
                }
            }
            //返回的result，接口调用结果Success: 更新成功；Failed：更新失败；Contains errors：部分数据未更新成功；
            //System.out.println("getResult=" + authenticationInfoListResponse.getResult());
            log.info("getResult=" + authenticationInfoListResponse.getResult());
        }

        return authenticationInfoListResponse;
    }


    /**
     * @param
     * @return AuthenticationInfoListResponse实体对象
     * @url ConstantConfig.Save_Corp_Cust_Info_List_Address
     */
    public AuthenticationInfoListResponse sendData(AuthenticationListRequst batchData) {
        String json = JsonUtil.toJson(batchData);
        String url = ConstantConfig.Save_Corp_Cust_Info_List_Address;
        //AuthenticationInfoListResponse authenticationInfoListResponse= HttpUtil.sendPostRequest(url, json);
        // 创建 HttpComponentsClientHttpRequestFactory 对象
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        // 设置超时时间，单位为毫秒
        requestFactory.setConnectTimeout(ConstantConfig.CONNECT_TIMEOUT); // 连接超时时间,120s
        requestFactory.setReadTimeout(ConstantConfig.READ_TIMEOUT); // 读取超时时间120s

        // 将 HttpComponentsClientHttpRequestFactory 对象设置为 RestTemplate 的请求工厂
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>(json, headers);

        String responseJson = restTemplate.postForObject(url, entity, String.class);
        AuthenticationInfoListResponse authenticationInfoListResponse = JsonUtil.fromJsonToAuthenticationInfoListResponse(responseJson);
        return authenticationInfoListResponse;
    }


}




